/**
 * 
 */
package com.livemeter;

import java.util.UUID;

import com.livemeter.R;

import android.app.AlertDialog;
import android.app.TabActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Vibrator;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TabHost;


/**
 *
 *Activity for logging in
 */
public class LoginActivity extends TabActivity 
{
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {   		
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login_activity);

        loadSettings();
               
    	Log.i("LIM", "Starting LIM_ENGINE!");
        Intent svc = new Intent(this, LIM_Engine.class);
        bindService(svc, serviceConnection, Context.BIND_AUTO_CREATE);
        
        // Setup Tab Widget
        TabHost mTabHost = getTabHost();
        mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator(this.getString(R.string.Online)).setContent(R.id.onlineTab));
        //if (LIM_Engine.historyActive)
        {
        	mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator(this.getString(R.string.History)).setContent(R.id.historyTab));
        }
        mTabHost.setCurrentTab(0);

       

        View incGroupButton = findViewById(R.id.incGroupName);
        incGroupButton.setOnClickListener(new OnClickListener() {
        	public void onClick(View v) {LoginActivity.this.onIncGroupClicked();}
        } );

        View joinButton = findViewById(R.id.joinButton);
        joinButton.setOnClickListener(new OnClickListener() {
        	public void onClick(View v) {LoginActivity.this.onJoinClicked();}
        } );
        
        /*View createButton = findViewById(R.id.createButton);
        createButton.setOnClickListener( new OnClickListener() {
        	public void onClick(View v) {LoginActivity.this.onCreateClicked();}
        } );*/
    }
    
    private ServiceConnection serviceConnection = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			final LIM_Engine lim = LIM_Engine.getInstance();
	        
	        if (LIM_Engine.historyActive)
			{
		        // setup history list view
		        ListView history_lv = (ListView)findViewById(R.id.historyListView);
		    	ArrayAdapter<String> adapter = new ArrayAdapter<String> (LoginActivity.this, android.R.layout.simple_list_item_1);
		    	adapter.setDropDownViewResource(android.R.layout.simple_list_item_1);
		    	for(String groupName : lim.history_GetGroupNames())
		    	{
		    		adapter.add(groupName);
		    	}
		    	history_lv.setAdapter(adapter);
		    	
		    	final LIM_Event_Listener historyEventListener = new LIM_Event_Listener() {
		    		@Override
		    		public void meterOpened(LIM_MeterEvent evt) {
		            	//invoke client input meter activity
		    			Log.i("LIM-SA", "Meter opened: "+evt.meter.getTitle());
		                Intent intent = new Intent(Intent.ACTION_VIEW);
				        intent.putExtra("historymodeActive", true);
		                intent.putExtra("MeterTitle", evt.meter.getTitle());
		                intent.setClassName(LoginActivity.this, InputMeterActivity.class.getName());
		                startActivity(intent);
		                // Block the execution of the loading until the InputMeterActivity is properly resumed
		                // and its event listeners are registered
		                final InputMeterActivity ima = InputMeterActivity.getIMA(evt.meter.getTitle());
						ima.beginLoading();
		    		}
		    		@Override
		    		public void meterClosed(LIM_MeterEvent evt) {}
		    		@Override
		    		public void meterValueChanged(LIM_MeterValueEvent evt) {}
		    		@Override
		    		public void pollOpened(LIM_PollEvent evt) 
		    		{
		    			/*if(LIM_Engine.getInstance().isMaster()) //only clients can answer to poll
		    				return;
		    			Log.i("LIM-SA", "Poll opened: "+evt.poll.getTitle());
		    			
		    			//show activity to answer poll
		    			Intent intent = new Intent(Intent.ACTION_VIEW);
		    	        intent.setClassName(SetupActivity.this, AnswerPollActivity.class.getName());
		    	        intent.putExtra("PollTitle", evt.poll.getTitle());
		    	        startActivity(intent);*/
		    		}
		    		@Override
		    		public void pollUpdated(LIM_PollEvent evt) {}
		    		@Override
		    		public void pollClosed(LIM_PollEvent evt) {}
		    		@Override
		    		public void topicStamp(LIM_TopicStampEvent evt) {}
		    		@Override
		    		public void questionsChanged() {}
					@Override
					public void setupTimeout() {}
					@Override
					public void tick() {}
		    	};
		    	
		        history_lv.setClickable(true);
		        history_lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
					@Override
					public void onItemClick(AdapterView<?> adapter, View view, int position,long id) {
						final String groupName = (String)adapter.getItemAtPosition(position);
						new Thread(new Runnable() {
							public void run() {
						    	Poll.clearAll();Meter.clearAll();Topic.clearAll();InputMeterActivity.clearIMAs();
						    	// Otherwise the stuff will not really be deleted!
						    	System.gc();
						    	lim.reset();
						    	lim.history_startHistoryMode();
								// Clear all previous LIM-Event-Listeners
								lim.removeAllEventListeners();
								// Install a LIM-Event-Listener to open new Meters in read only mode
								lim.addEventListener(historyEventListener);
								// Load the groups events
								lim.history_LoadGroup(groupName);
								// Clear LIM-Event-Listeners again
								lim.removeAllEventListeners();
								for (final InputMeterActivity ima : InputMeterActivity.getIMAs())
								{
									runOnUiThread(new Runnable() {
									    public void run() {
									    	ima.endLoading(true);
									    }
									});
								}
							}
						}).start(); 
					}
		        });
			}
		}
		@Override
		public void onServiceDisconnected(ComponentName name) {}
    };
    
    @Override
    protected void onRestart() {
    	super.onRestart();
    	LIM_Engine lim = LIM_Engine.getInstance();
    	if (lim != null)
    	{
            if (LIM_Engine.historyActive)
    		{
		        // setup history list view
		        ListView history_lv = (ListView)findViewById(R.id.historyListView);
		    	ArrayAdapter<String> adapter = new ArrayAdapter<String> (LoginActivity.this, android.R.layout.simple_list_item_1);
		    	adapter.setDropDownViewResource(android.R.layout.simple_list_item_1);
		    	for(String groupName : lim.history_GetGroupNames())
		    	{
		    		adapter.add(groupName);
		    	}
		    	history_lv.setAdapter(adapter);
    		}
    	}
    	resetUI();
    }
    
    protected void resetUI()
    {
    	Button joinButton = (Button)findViewById(R.id.joinButton);
    	joinButton.setClickable(true);
    	joinButton.setText(R.string.Join);
    	/*Button createButton = (Button)findViewById(R.id.createButton);
    	createButton.setClickable(true);
    	createButton.setText(R.string.Create);*/
    }
    
    @Override
    protected void onPause() {
    	saveSettings();
    	super.onPause();
    }
    
    @Override
    protected void onDestroy() {
    	Log.i("LIM", "Stopping LIM_ENGINE!");
    	unbindService(serviceConnection);
        super.onDestroy();
    }
    
    private String m_id;
    private String m_pwd;
   
    protected void generateNewID() 
    {
    	String res = UUID.randomUUID().toString();
    	res.replace('-', '_');
    	m_id = "lim_"+res.substring(0,8);
    	m_pwd = res.substring(res.length()-13,res.length());
    }

    private String getServer() {return ((EditText)findViewById(R.id.serverTextbox)).getText().toString();}
    private String getID() {return m_id;}
    private String getPwd() {return m_pwd;}
    private void setServer(String srv) { if(srv == null)return; ((EditText)findViewById(R.id.serverTextbox)).setText(srv);}
 
    private String getGroupName() {return ((EditText) LoginActivity.this.findViewById(R.id.groupNameTextbox)).getText().toString();}
    private void setGroupName(String name) {((EditText) LoginActivity.this.findViewById(R.id.groupNameTextbox)).setText(name);}

    //private String getGroupPwd() {return ((EditText) LoginActivity.this.findViewById(R.id.groupPasswordTextbox)).getText().toString();}
    //private void setGroupPwd(String pwd) {((EditText) LoginActivity.this.findViewById(R.id.groupPasswordTextbox)).setText(pwd);}
    private String getGroupPwd() {return "" ;}

	
    private final String settingsName = "LoginSettings";
	
	protected void loadSettings()
	{
		SharedPreferences settings = getSharedPreferences(settingsName, 0);
	
		setGroupName(settings.getString("group", "group01"));
		//setGroupPwd(settings.getString("pwd", ""));

		setServer(settings.getString("host", "lim.nts.com.de"));
		m_id = settings.getString("gid", "");
		m_pwd = settings.getString("gpwd", "");
		
		if ((m_id.length() == 0) || (m_pwd.length() == 0)) 
			generateNewID();
	}
	
	protected void saveSettings()
	{
		SharedPreferences settings = getSharedPreferences(settingsName, 0);
		SharedPreferences.Editor editor = settings.edit();
		editor.putString("host", getServer());
		editor.putString("gid", getID());
		editor.putString("gpwd", getPwd());
		editor.putString("group", getGroupName());
		
		//editor.putString("pwd", getGroupPwd());

		// Commit the edits!
		editor.commit();
	}
	
    private boolean checkSettings()
    {
    	if(getGroupName().length() == 0)
    	{
			AlertDialog alertDialog;
			alertDialog = new AlertDialog.Builder(LoginActivity.this).create();
			alertDialog.setTitle(this.getString(R.string.InvalidGroupName));
			alertDialog.setMessage(this.getString(R.string.ErrorNameEmpty));
			alertDialog.show();
    		return false;
    	}
    	/*if(getGroupPwd().length() == 0)
    	{
			AlertDialog alertDialog;
			alertDialog = new AlertDialog.Builder(LoginActivity.this).create();
			alertDialog.setTitle(this.getString(R.string.InvalidGroupPassword));
			alertDialog.setMessage(this.getString(R.string.ErrorPasswordEmpty));
			alertDialog.show();
    		return false;
    	}*/
    	return true;
    }
	
    private boolean login()
    {
    	LIM_Engine lim = LIM_Engine.getInstance();
    	if (lim.connect(getServer()) && (lim.login(getID(), getPwd())))
   		{
    		// Check if the app has been closed in the meantime!
    		return LIM_Engine.getInstance() != null;
    	} else {
    		AlertDialog alertDialog = new AlertDialog.Builder(LoginActivity.this).create();
			alertDialog.setTitle(lim.lastError());
			alertDialog.setMessage(lim.lastErrorLong());
			alertDialog.show();
			resetUI();
			return false;
    	}
    }
    
	private void onIncGroupClicked()
	{
		String groupName = getGroupName();
		int i = groupName.length()-1;
		while ((i >= 0) && (Character.isDigit(groupName.charAt(i))))
		{
			--i;
		}
		String numberStr = groupName.substring(i+1, groupName.length());
		int number;
		try {
			number = Integer.parseInt(numberStr)+1;
		} catch (NumberFormatException e) {
			number = 1;
		}
		setGroupName(groupName.substring(0,i+1)+String.valueOf(number));
	}
	
    private void onJoinClicked() 
    {
    	if (!checkSettings()) return;

    	Button joinButton = (Button)findViewById(R.id.joinButton);
    	joinButton.setClickable(false);
    	joinButton.setText(R.string.Joining);

    	Poll.clearAll();Meter.clearAll();Topic.clearAll();
    	LIM_Engine.getInstance().reset();

    	Handler handler = new Handler(); 
        handler.postDelayed(new Runnable() {
            public void run() {
            	if (login())
            	{
                	LIM_Engine lim = LIM_Engine.getInstance();
	        		lim.removeAllEventListeners();
            		lim.addEventListener(m_clientLIMEventListener);
	            	if (lim.client_JoinGroup(getGroupName(), getGroupPwd()))
	           		{
	            	} else {
	            		AlertDialog alertDialog = new AlertDialog.Builder(LoginActivity.this).create();
	        			alertDialog.setTitle(lim.lastError());
	        			alertDialog.setMessage(lim.lastErrorLong());
	        			alertDialog.show();
	        			resetUI();
	            	}
            	}
            }
            }, 100); 
	}

/*	private void onCreateClicked() 
	{
    	if (!checkSettings()) return;
    	Button createButton = (Button)findViewById(R.id.createButton);
    	createButton.setClickable(false);
    	createButton.setText(R.string.Creating);
    	
    	Poll.clearAll();Meter.clearAll();Topic.clearAll();
    	LIM_Engine.getInstance().reset();
    	
    	Handler handler = new Handler(); 
        handler.postDelayed(new Runnable() {
            public void run() {
            	if (login())
            	{
			    	LIM_Engine lim = LIM_Engine.getInstance();
			    	if (lim.master_CreateGroup(getGroupName(), getGroupPwd()))
			   		{
			    		//invoke setup meter activity
			            Intent intent = new Intent(Intent.ACTION_VIEW);
			            intent.setClassName(LoginActivity.this, SetupMasterActivity.class.getName());
			            startActivity(intent);  
			    	} else {
			    		AlertDialog alertDialog = new AlertDialog.Builder(LoginActivity.this).create();
						alertDialog.setTitle(lim.lastError());
						alertDialog.setMessage(lim.lastErrorLong());
						alertDialog.show();
	        			resetUI();
			    	}
            	}
            }
        }, 100); 
	}*/
    
	private int m_setupTimeoutCounter = 0;

	final LIM_Event_Listener m_clientLIMEventListener = new LIM_Event_Listener() {
		@Override
		public void meterOpened(LIM_MeterEvent evt) {
			// Get instance of Vibrator from current Context
			Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
			// Vibrate for 300 milliseconds
			v.vibrate(200);
        	//invoke client input meter activity
			Log.i("LIM-SA", "Meter opened: "+evt.meter.getTitle());
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.putExtra("MeterTitle", evt.meter.getTitle());
            intent.setClassName(LoginActivity.this, InputMeterActivity.class.getName());
            startActivity(intent);
		}
		@Override
		public void meterClosed(LIM_MeterEvent evt) {}
		@Override
		public void meterValueChanged(LIM_MeterValueEvent evt) {}
		@Override
		public void pollOpened(LIM_PollEvent evt) 
		{
			// Get instance of Vibrator from current Context
			Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
			// Vibrate for 300 milliseconds
			v.vibrate(200);
			if (!LIM_Engine.getInstance().isClient()) //only clients can answer to poll
				return;
			Log.i("LIM-SA", "Poll opened: "+evt.poll.getTitle());
			
			//show activity to answer poll
			Intent intent = new Intent(Intent.ACTION_VIEW);
	        intent.setClassName(LoginActivity.this, AnswerPollActivity.class.getName());
	        intent.putExtra("PollTitle", evt.poll.getTitle());
	        startActivity(intent);
		}
		@Override
		public void pollUpdated(LIM_PollEvent evt) {}
		@Override
		public void pollClosed(LIM_PollEvent evt) {}
		@Override
		public void questionsChanged() {}
		@Override
		public void tick() {}
		@Override
		public void topicStamp(LIM_TopicStampEvent evt) {}
		@Override
		public void setupTimeout() 
		{
			if (m_setupTimeoutCounter < 1)
			{
				++m_setupTimeoutCounter;
				LoginActivity.this.generateNewID();
				onJoinClicked();
			} else {
				m_setupTimeoutCounter = 0;
	    		AlertDialog alertDialog = new AlertDialog.Builder(LoginActivity.this).create();
				alertDialog.setTitle(LoginActivity.this.getString(R.string.ConnectionError));
				alertDialog.setMessage(LoginActivity.this.getString(R.string.TimeoutError));
				alertDialog.show();
    			resetUI();
			}
		}
	};
}
